// Keywords: survival(), sperm storage

// This model is loosely based upon a model by Anita Lerch.

initialize() {
	initializeSLiMModelType("nonWF");
	initializeSLiMOptions(keepPedigrees=T);
	initializeSex();
	defineConstant("K", 500);
	
	initializeMutationRate(1e-7);
	initializeMutationType("m1", 0.5, "f", 0.0);
	m1.convertToSubstitution = T;
	initializeGenomicElementType("g1", m1, 1.0);
	initializeGenomicElement(g1, 0, 99999);
	initializeRecombinationRate(1e-8);

}
reproduction(p1) {
	matureFemales = subpop.subsetIndividuals(sex="F", minAge=7);
	
	for (female in matureFemales)
	{
		if (female.tag < 0) {
			// the female has not yet chosen a mate, so choose one now
			mate = subpop.sampleIndividuals(1, sex="M", minAge=7);
		} else {
			// the female has already chosen a mate; look it up by id
			mate = sim.individualsWithPedigreeIDs(female.tag);
		}
		if (mate.size()) {
			female.tag = mate.pedigreeID;
			subpop.addCrossed(female, mate, count=rpois(1, 5));
		} else {
			catn(sim.cycle + ": No mate found for tag " + female.tag);
		}
	}
	self.active = 0;
}
1 early() {
	sim.addSubpop("p1", 100);
	p1inds = p1.individuals;
	p1inds.age = rdunif(size(p1.individuals), min=0, max=10);
	p1inds.tag = -1;
	
	sim.addSubpop("p1000", 0);   // cold storage for dead males
}
early() {
	// fix all new female tags; faster to do this vectorized
	offspringFemales = p1.subsetIndividuals(sex="F", maxAge=0);
	offspringFemales.tag = -1;
	
	// p1 is governed by standard density-dependence
	p1.fitnessScaling = K / p1.individualCount;
	
	// cold storage individuals are kept until unreferenced
	p1000.individuals.tag = 0;
	maleRefs = p1.subsetIndividuals(sex="F").tag;
	maleRefs = maleRefs[maleRefs != -1];
	referencedDeadMales = sim.individualsWithPedigreeIDs(maleRefs, p1000);
	referencedDeadMales.tag = 1;
}
survival(p1) {
	// move dying males into cold storage in case they have mated
	if (!surviving)
		if (individual.sex == "M")
			return p1000;
	return NULL;
}
survival(p1000) {
	return (individual.tag == 1);
}
late() {
	catn(sim.cycle + ": p1 (" + p1.individualCount + ")" +
		", p1000 (" + p1000.individualCount + ")");
}
10000 late() {
	sim.outputFixedMutations();
}
